package com.cy.pj.goods.dao;
//公司域名（com.cy）+项目名（project）+模块（goods）+层（Dao）一般指数据访问层

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*jdbc会自动关联HikariCP连接池的依赖
* 此对象为一个商品数据层访问对象，现在要求此类中定义一个方法，这个方法基于JDBC从数据库获取商品信息，
* 并将其封装到map集合，要求一个行记录一个map对象（key为表中字段名，值为字段名对应的值），多个map存储到list集合
* */
@Repository //此注解通常用于描述数据层实现类对象，本质上就是一个特殊的@Component,都是交给spring管理的bean对象
public class DefaultGoodsDao implements GoodsDao{
    //这个怎么写由spring给砸门注入一个数据源对象，这个类关联了一个属性DataSource，这个接口的实现类关联
    // 了一个连接池，所以要通过接口找到对应的连接池对象，所以耦合于这个接口规范
    @Autowired
    private DataSource dataSource;//访问hikariCP池对象拿连接
    /*查询商品信息，一行记录映射为内存中的一个map对象，多行放到list集合 */
    public List<Map<String,Object>> findGoods(){
        Connection conn=null;//java.sql.*
        Statement stmt=null;//statemenet传送器发送sql         这些都属于jdbc的api
        ResultSet rs=null;
        String sql="select * from tb_goods";
        //String sql="select id,name,remark as note,createdTime from tb_goods";
        //1.获取连接（从连接池获取）
        try {
            conn=dataSource.getConnection();
            //2.创建statement对象，从池拿到连接
            stmt= conn.createStatement();
            //stmt= conn.prepareStatement(sql:);
            //3.通过statement发送sql
            rs=stmt.executeQuery(sql);//写好的sql语句发送给数据库端，数据库返回结果ResultSet
            //4.处理结果,数据库存储数据以二维表的形式存储rs.next移动一下指针
            List<Map<String,Object>> list=new ArrayList<>();
            while (rs.next()){//循环一次取一行，一行记录映射为一个map对象,进行行映射创建map把数据封装起来
               /* Map<String,Object> rowMap=new HashMap<>();//构建map对象哈希
                rowMap.put("id",rs.getInt("id"));
                rowMap.put("name",rs.getString("name"));
                rowMap.put("remark",rs.getString("remark"));
                rowMap.put("createdTime",rs.getTimestamp("createdTime"));*/
                list.add(rowMap(rs));//将存储了一行记录的map对象再存储到list集合
            }
            return list;
        }catch (SQLException e){
            e.printStackTrace();
            throw new RuntimeException(e);//转化为非检查异常（编译时不检测的异常）
        }finally {
            //5.释放资源
            /*if(rs!=null)try{ rs.close();}catch (Exception e){e.printStackTrace();}
            if(stmt!=null)try{ stmt.close();}catch (Exception e){e.printStackTrace();}
            if(conn!=null)try{ conn.close();}catch (Exception e){e.printStackTrace();}*/
            close(rs,stmt,conn);
        }
    }
    private Map<String,Object> rowMap(ResultSet rs)throws SQLException{
        Map<String,Object> rowMap=new HashMap<>();//构建map对象哈希
        //rowMap.put("id",rs.getInt("id"));
        //rowMap.put("name",rs.getString("name"));
       // rowMap.put("remark",rs.getString("remark"));
       // rowMap.put("createdTime",rs.getTimestamp("createdTime"));
        ResultSetMetaData rsmd =rs.getMetaData();//获取元数据（包括表中的字段名）
        int columCount=rsmd.getColumnCount();//获取列的数量
        for (int i=0;i<columCount;i++){
            rowMap.put(rsmd.getColumnLabel(i+1),rs.getObject(rsmd.getColumnLabel(i+1)));
            //getColumLabel(i+1);获取表中字段名或字段名对应的别名
        }
        //rowMap.put(columName,rs.getObject(columName));
        return rowMap;
    }
    private void close(ResultSet rs,Statement stmt,Connection conn){
        if(rs!=null)try{ rs.close();}catch (Exception e){e.printStackTrace();}
        if(stmt!=null)try{ stmt.close();}catch (Exception e){e.printStackTrace();}
        if(conn!=null)try{ conn.close();}catch (Exception e){e.printStackTrace();}
    }
}
